package cn.pconline.autoclub.service;

import cn.pconline.autoclub.entity.Club;
import cn.pconline.autoclub.entity.User;
import cn.pconline.passport2.util.T;
import cn.pconline.r.client.EntityBuilder;
import cn.pconline.r.client.ResponseExtractor;
import cn.pconline.r.client.SimpleHttpTemplate;
import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.util.EntityUtils;
import org.gelivable.dao.GeliDao;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 民间车友会审核服务类 
 */
public abstract class CensorService {

    @Autowired
    private ClubService clubService;
    @Autowired
    protected SimpleHttpTemplate simpleHttpTemplate4Censor;
    @Autowired
    protected GeliDao geliDao;
    protected static final org.slf4j.Logger log = LoggerFactory.getLogger(CensorService.class);
    // MUST
    public final static String SITE = "site";
    public final static String APP = "app";
    public final static String TYPEID = "typeId";
    public final static String ISNEW = "isNew";
    public final static String URI = "uri";
    public final static String VERSION = "version";
    public final static String USERID = "userId";
    public final static String USERNAME = "userName";
    public final static String IP = "ip";
    public final static String STATUS = "status";
    public final static String CONTENT = "content";
    public final static String TITLE = "title";
    public final static String UPDATEAT = "updateAt";
    //发消息队列同步昵称时用的appName和actionType
    public final static String APP_NAME = "common";
    public final static String ACTION_TYPE = "updateNickName";
    // CHANGE STATUS
    public static final int CENSORSYSTEM_RESPONSE_PASS = 2;
    public static final int CENSORSYSTEM_RESPONSE_DENY = 3;
    //车友会类型
    public static final int CLUB_TYPE_OFFICIAL = 1; //品牌车友会
    public static final int CLUB_TYPE_COMMON = 0;  //普通车友会
    protected ExecutorService executorService;
    protected String receiveHome;
    protected String statusChangeHome;
    protected int site;
    protected boolean csr_switch;

    public void setSite(int site) {
        this.site = site;
    }
    // 连接超时时间
    // public static int TIMEOUT = 20;
    // Executors的连接池数??
    protected final static int POOLSIZE = 50;
    protected String censorDomain;
    protected String appName;
    protected String httpsqsUrl;
    /**
     * 此参数是为测试时有二级目录
     */
    private String proName;

    public void setCensorDomain(String censorDomain) {
        this.censorDomain = censorDomain;
    }

    public void setSimpleHttpTemplate4Censor(
            SimpleHttpTemplate simpleHttpTemplate4Censor) {
        this.simpleHttpTemplate4Censor = simpleHttpTemplate4Censor;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    public void setProName(String proName) {
        this.proName = proName;
    }

    public String getHttpsqsUrl() {
        return httpsqsUrl;
    }

    public void setHttpsqsUrl(String httpsqsUrl) {
        this.httpsqsUrl = httpsqsUrl;
    }

    public void init() {
        executorService = Executors.newFixedThreadPool(POOLSIZE);
        receiveHome = "http://"
                + censorDomain
                + (proName != null && !"".contains(proName) ? ("/" + proName)
                : "") + "/receive.jsp";
        statusChangeHome = "http://" + censorDomain + (proName != null && !"".contains(proName) ? ("/" + proName) : "") + "/updateIndexReceive.jsp";
        csr_switch = true;
    }

    public void shutdown() {
        executorService.shutdown();
        simpleHttpTemplate4Censor.shutdown();
    }

    /**
     * 将ClubNotice类转换成向审核系统传递的参数,只用在新建留言时
     *
     * @param request
     * @param user
     * @param id
     * @param typeId
     * @param content
     * @param isNew
     * @param time
     * @return
     */
    protected Map<String, Object> convert4Create(HttpServletRequest request, User user,
            long clubId, long typeId, String content, long time, boolean isNew, int type) {
        Map<String, Object> map = new HashMap<String, Object>(16);
        //标题
        map.put(TITLE, content);
        map.put(SITE, site);
        map.put(APP, appName);
        map.put(TYPEID, typeId);
        map.put(ISNEW, isNew ? 1 : 0);
        // uri formate : "http://my.pcauto.com.cn/520?typeId=331";
        // map.put(URI, "http://my.pcauto.com.cn/" + accountInfo.getId() + "?typeId=" + typeId
        String root = "http://" + T.stringValue(request.getHeader("host"), "") + T.stringValue(request.getContextPath(), "");
        Club club = clubService.getClub(clubId);
        if (club != null) {
            map.put(URI, root + "/" + club.getClubUrl() + "/?typeId=" + typeId + "&clubId=" + clubId + "&clubType=" + type);
        }
        map.put(VERSION, (time / 1000) * 1000);
        map.put(USERID, user == null ? " " : user.getUid());
        map.put(USERNAME, user == null ? " " : user.getUsername());
        map.put(IP, T.getIp(request));
        map.put(CONTENT, content);
        return map;
    }

    /**
     *
     * @param request
     * @param user
     * @param id
     * @param typeId
     * @param time
     * @return
     */
    protected Map<String, Object> convert4DeleteAndRestore(HttpServletRequest request, User user,
            long id, long typeId, long time) {
        Map<String, Object> map = new HashMap<String, Object>(6);
        map.put(APP, appName);
        String root = "http://" + T.stringValue(request.getHeader("host"), "") + T.stringValue(request.getContextPath(), "");
        map.put(URI, root + "/" + id + "?typeId="
                + typeId);
        map.put(STATUS, CENSORSYSTEM_RESPONSE_DENY);
        //应用对内容的更新时间，需要转化为毫秒进行传输
        map.put(UPDATEAT, (time / 1000) * 1000);
        map.put(USERID, user == null ? " " : user.getUid());
        map.put(USERNAME, user == null ? " " : user.getUsername());
        return map;
    }

    /**
     * interface ResponseExtractor comes from R, not Spring
     */
    class CensorResponseExtractor implements ResponseExtractor<CensorService.CensorResult> {

        @Override
        public CensorService.CensorResult extractData(HttpResponse paramHttpResponse)
                throws IOException {
            StatusLine status = paramHttpResponse.getStatusLine();
            CensorService.CensorResult result = null;
            int sc = status.getStatusCode();
            if ((sc >= 200) && (sc <= 300)) {
                HttpEntity responseEntity = paramHttpResponse.getEntity();
                result = null;
                if (responseEntity != null) {
                    result = new CensorService.CensorResult();
                    result.setResult(EntityUtils
                            .toString(responseEntity, "GBK"));
                }
            } else {
                log.error("censor post error : " + sc);
                log.error("censor post error1 : " + status.getReasonPhrase());
                log.error("censor post error1 : " + status.getProtocolVersion());
                HttpEntity responseEntity = paramHttpResponse.getEntity();
                if (responseEntity != null) {
                    log.error(EntityUtils.toString(responseEntity, "GBK"));
                }
            }
            return result;
        }
    }

    class CensorResult {

        private String result;

        public String getResult() {
            return result;
        }

        public void setResult(String result) {
            this.result = result;
        }
    }

    class CensorCall implements Callable<Object> {

        private String url;
        private Map<String, Object> params;

        public CensorCall(String url, Map<String, Object> params) {
            this.url = url;
            this.params = params;
        }

        @Override
        public Object call() throws Exception {
            String result = post(params, url);
            if (result != null && result.length() < 50) {
                result = result.replaceAll("\r\n", "");
            }
            if (result != null || !"".equals(result)) {
                log.info(result);
            }
            return 0;
        }

        /**
         *
         * @param params
         * @param url
         * @return
         */
        private String post(Map<String, Object> params, String url) {
            EntityBuilder builder = EntityBuilder.entity("GBK");
            builder = builder.params(params);
            HttpEntity entity = builder.build();
            CensorService.CensorResult result = simpleHttpTemplate4Censor.post(url, null,
                    new CensorService.CensorResponseExtractor(), entity);
            String jsonString = result.getResult();
            return jsonString;
        }
    }

    /**
     * 审核平台返回url解析参数方法
     *
     * @param url like
     * http://club.pcauto.com.cn/gzqrcyh/comment/?typeId=100&clubId=200&commentId=300
     * @return
     */
    protected static Map<String, Long> getMapByUrl(String url) {
        Map<String, Long> map = new HashMap<String, Long>();
        if (StringUtils.isNotBlank(url) && url.contains("?")) {
            String urlArr = url.substring(url.indexOf("?") + 1, url.length());
            if (urlArr.contains("&")) {
                String[] valArr = urlArr.split("&");
                if (valArr.length > 0) {
                    for (String value : valArr) {
                        String[] val = value.split("=");
                        map.put(val[0], Long.parseLong(val[1]));
                    }
                }
            }
        }
        return map;
    }

    /**
     * 数据库的更新日期为datetime类型，比较时间戳的话，不精确
     *
     * @param time1
     * @param time2
     * @return
     */
    protected boolean isTheSameVersion(long time1, long time2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTimeInMillis(time1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTimeInMillis(time2);
        return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
                && cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR)
                && cal1.get(Calendar.HOUR_OF_DAY) == cal2.get(Calendar.HOUR_OF_DAY)
                && cal1.get(Calendar.MINUTE) == cal2.get(Calendar.MINUTE)
                && cal1.get(Calendar.SECOND) == cal2.get(Calendar.SECOND);
    }

    public static boolean isCommonClub(String url) {
        Map<String, Long> map = getMapByUrl(url);
        Long type = map.get("clubType");
        if (type != null) {
            if (type.intValue() == CLUB_TYPE_OFFICIAL) {
                return false;
            }
        }
        return true;
    }

    protected abstract boolean isCorrectFeedback(String url);
}
